/**
 * @file thread.h
 * @ingroup Thread
 *
 * @brief Thread super-class definition header
 */

/* --
 * Copyright (c) 2012, Christophe Huriaux
 * Distributed under the terms of the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 * --
 */

/**
 * @defgroup Thread
 * @ingroup Utilities
 * @brief Threading facilities
 */

#ifndef THREAD_H
#define THREAD_H

#include <string>

/** @class Thread
 *  @ingroup Thread
 *  @brief Thread super-class
 *
 *    Classes which needs to be ran as a separate thread could sub-class
 * @c Thread and reimplements the virtual function @c Thread::run() to be fully
 * threadable.
 *
 * @note The current @c Thread implementation relies on the pthread library to do
 * the dirty work behind the scene.
 */
class Thread
{
	std::string name;  //!< Thread name
	pthread_t id;      //!< Thread id (for internal references)
	bool alive;        //!< true if the thread is running, else false
	bool stopped;      //!< true is the thread should stop, else false

public:
	/** @name Constructor and destructor
	 * @{
	 */
	Thread(const char* name);
	virtual ~Thread() { };
	//!@}

	/** @name Thread state control
	 * @{
	 */
	int start();
	int stop();
	int join();
	int cancel();
	//!@}

protected:
	/** @name Thread static entry points
	 * @{
	 */
	static void* __threadEntryPoint(void* ptr);
	static void __threadCleanup(void* ptr);
	//!@}

	/** @name Thread callbacks
	 * @{
	 */
	void atCleanup();
	virtual void* run() = 0;
	//!@}

public:
	/** @name Thread informations
	 * @{
	 */

	/**
	 * @brief Return the thread name
	 *
	 * @return Thread name
	 */
    const char* getName() { return name.c_str(); }


    /**
     * @brief Return the thread ID
     *
     * @return Thread id
     */
	pthread_t getId() { return id; }


	/**
	 * @brief Check if the thread is running or not
	 *
	 * @retval true If the thread is currently running
	 * @retval false If it's not
	 */
	bool isAlive() { return alive; }


	/**
	 * @brief Check if a stop request has been emitted
	 *
	 * @retval true If the thread has to stop
	 * @retval false If not
	 */
	bool shouldStop() { return stopped; }
	//!@}
};

#endif // THREAD_H
